<template>
   <el-form label-width="100px" label-position="left">
      <el-form-item label="SPU名称">
         <el-input placeholder="请你输入SPU的名称" v-model="SpuParams.spuName"></el-input>
      </el-form-item>
      <el-form-item label="SPU品牌">
         <el-select placeholder="请你选择品牌" v-model="SpuParams.tmId">
            <el-option v-for="(item, index) in allTradeMark" :key="item.id" :label="item.tmName"
               :value="item.id"></el-option>
         </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
         <el-input type="textarea" placeholder="请你输入SPU的描述" v-model="SpuParams.description"></el-input>
      </el-form-item>
      <el-form-item label="SPU图片">
         <!-- v-model:file-list展示默认图片 -->
         <!-- action:上传图片的接口地址 -->
         <!-- list-type:文件列表类型 -->
         <el-upload v-model:file-list="imgList" action="/api/admin/product/fileUpload" list-type="picture-card"
            :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-upload="beforeUpload">
            <el-icon>
               <Plus />
            </el-icon>
         </el-upload>

         <el-dialog v-model="dialogVisible">
            <img w-full :src="dialogImageUrl" alt="Preview Image" style="width: 100%; height: 100%;" />
         </el-dialog>
      </el-form-item>
      <el-form-item label="SPU销售属性(不能为空)">
         <!-- 展示销售属性的下拉菜单 -->
         <el-select v-model="saleAttrIdAndValueName"
            :placeholder="unSelectedSaleAttr.length ? `还有未选择的销售属性${unSelectedSaleAttr.length}个` : '暂无属性可选择'">
            <el-option :value="`${item.id}:${item.name}`" v-for="item in unSelectedSaleAttr" :key="item.id"
               :label="item.name"></el-option>
         </el-select>
         <el-button type="primary" icon="Plus" style="margin-left: 10px;" @click="addSaleAttr"
            :disabled="saleAttrIdAndValueName ? false : true">添加销售属性</el-button>
         <!-- 展示销售属性和属性值的table -->
         <el-table border style="margin: 10px 0;" :data="saleAttr">
            <el-table-column label="序号" type="index" align="center" width="100px"></el-table-column>
            <el-table-column label="属性名" width="100px" prop="saleAttrName"></el-table-column>
            <el-table-column label="属性值">
               <template #="{ row, $index }">
                  <el-tag v-for="(item, index) in row.spuSaleAttrValueList" :key="item.id" class="mx-1" closable
                     style="margin: 0 5px;" @close="row.spuSaleAttrValueList.splice(index, 1)">
                     {{ item.saleAttrValueName }}
                  </el-tag>
                  <el-input @blur="toLook(row)" v-model="row.saleAttrValue" v-if="row.flag == true" placeholder="请你输入属性值"
                     size="small" style="width: 100px;"></el-input>
                  <el-button @click="toEdit(row)" v-else type="primary" icon="Plus" size="small"></el-button>
               </template>
            </el-table-column>
            <el-table-column label="操作" width="100px">
               <template #="{ row, $index }">
                  <el-button type="primary" icon="Delete" size="small" @click="saleAttr.splice($index, 1)"></el-button>
               </template>
            </el-table-column>
         </el-table>
         <el-button type="primary" @click="save" :disabled="saleAttr.length > 0 ? false : true">保存</el-button>
         <el-button @click="cancel">取消</el-button>
      </el-form-item>
   </el-form>
</template>

<script setup lang="ts">
import type { SpuImgArr, SaleAttrValue, TradeMark, AllSaleAttr, SaleAttr, SpuImg, SpuData, AllTradeMarkResponseData, SpuHasImgResponseData, SpuSaleAttrResponseData, AllSaleAttrResponseData } from '@/api/product/spu/type'
import { reqAllTradeMark, reqAllSaleAttr, reqSpuImageList, reqSpuHasSaleAttr, reqAddOrUpdateSpu } from '@/api/product/spu/index'
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
let $emit = defineEmits(['changeScene'])
// 存储已有的SPU的数据
// 全部品牌的数据
let allTradeMark = ref<TradeMark[]>([])
// 照片墙的数据
let imgList = ref<SpuImgArr>([])
// 已有的SPU销售属性
let saleAttr = ref<SaleAttr[]>([])
// 全部的销售属性
let allSaleAttr = ref<AllSaleAttr[]>([])
// 存储已有的SPU对象
let SpuParams = ref<SpuData>({
   spuName: "",  //SPU的名称
   description: "", //SPU的描述
   category3Id: "", //三级分类id
   tmId: "",  //对应品牌的id
   spuSaleAttrList: [], //销售属性数据
   spuImageList: [],   //商品已有图片的数据
})
// 控制对话框的显示和隐藏效果
let dialogVisible = ref<boolean>(false)
// 存储预览图片的地址
let dialogImageUrl = ref<string>('')
// 用来收集还未选择的销售属性的id与属性值的名字
let saleAttrIdAndValueName = ref<string>('')
// 取消按钮的回调
const cancel = () => {
   $emit('changeScene', { flag: 0, params: 'update' })
}
// 修改一个SPU初始化数据请求方法
const initHasSpuData = async (spu: SpuData) => {
   // 存储已有的SPU对象，之后在模板中展示
   // spu:即为父组件传递过来的已有的SPU对象(不完整)
   SpuParams.value = spu
   // 获取全部品牌的数据
   let result: AllTradeMarkResponseData = await reqAllTradeMark()
   // 获取某一品牌下全部售卖商品的图片
   let result1: SpuHasImgResponseData = await reqSpuImageList((spu.id as number))
   // 获取SPU已有的的销售属性
   let result2: SpuSaleAttrResponseData = await reqSpuHasSaleAttr((spu.id) as number)
   // 获取SPU全部的销售属性
   let result3: AllSaleAttrResponseData = await reqAllSaleAttr()

   // 存储全部品牌的数据
   allTradeMark.value = result.data
   // 存储图片的数据
   imgList.value = result1.data.map(item => {
      return {
         name: item.imgName,
         url: item.imgUrl
      }
   })
   // 存储已有的销售属性
   saleAttr.value = result2.data
   // 存储全部销售属性
   allSaleAttr.value = result3.data
}
// 添加一个新的SPU的初始化数据请求方法
const initAddSpu = async (c3Id: number | string) => {
   // 在添加之前清空之前的数据
   Object.assign(SpuParams.value, {
      spuName: "",  //SPU的名称
      description: "", //SPU的描述
      category3Id: "", //三级分类id
      tmId: "",  //对应品牌的id
      spuSaleAttrList: [], //销售属性数据
      spuImageList: [],   //商品已有图片的数据
   })
   // 清空照片墙数据
   imgList.value = []
   // 清空已有销售属性
   saleAttr.value = []
   saleAttrIdAndValueName.value = ''
   // 存储三级分类的ID
   SpuParams.value.category3Id = c3Id
   // 获取SPU全部的销售属性
   let result1: AllSaleAttrResponseData = await reqAllSaleAttr()
   // 获取全部品牌的数据
   let result2: AllTradeMarkResponseData = await reqAllTradeMark()
   // 存储数据
   allSaleAttr.value = result1.data
   allTradeMark.value = result2.data
}
// 对外暴露
defineExpose({ initHasSpuData, initAddSpu })
// 照片墙点击预览按钮触发的钩子
const handlePictureCardPreview = (file: any) => {
   // 显示对话框
   dialogVisible.value = true
   dialogImageUrl = file.url
}
// 照片墙点击删除时触发的钩子
const handleRemove = () => {
   console.log(123)
}
// 照片上传成功之前的钩子约束文件的类型和大小
const beforeUpload = (file: any) => {
   if (file.type == 'image/png' || file.type == 'image/jpeg' || file.type == 'image/gif') {
      if (file.size / 1024 / 1024 < 4) {
         return ElMessage.success('上传成功')
      } else {
         return ElMessage.error('上传图片超过4M，上传失败！')
      }
   } else {
      return ElMessage.error('上传图片格式应为png/jpg/gif! ')
   }
}
// 计算出当前SPU还未拥有的销售属性
let unSelectedSaleAttr = computed(() => {
   let unSelectedArr = allSaleAttr.value.filter(item => {
      return saleAttr.value.every(item1 => {
         return item.name != item1.saleAttrName
      })
   })
   return unSelectedArr
})
// 添加销售属性的方法
const addSaleAttr = () => {
   const [baseSaleAttrId, saleAttrName] = saleAttrIdAndValueName.value.split(':')
   // 准备一个新的销售属性对象：将来带给服务器
   let newSaleAttr: SaleAttr = {
      baseSaleAttrId,
      saleAttrName,
      spuSaleAttrValueList: []
   }
   // 追加到已有的销售属性数组中
   saleAttr.value.push(newSaleAttr)
   // 清空用来收据数据的变量
   saleAttrIdAndValueName.value = ''
}
// 属性值按钮的点击事件
const toEdit = (row: SaleAttr) => {
   // 点击按钮切换到编辑模式：显示input组件
   row.flag = true
   row.saleAttrValue = ''
}
// input组件失去焦点的方法的回调
const toLook = (row: SaleAttr) => {
   // 整理收集属性的ID和属性值的名字
   const { baseSaleAttrId, saleAttrValue } = row
   // 整理成服务器需要的属性值的形式
   let newSaleAttrValue: SaleAttrValue = {
      baseSaleAttrId,
      saleAttrValueName: (saleAttrValue as string)
   }
   // 非法情况判断
   // 1.不能为空
   if (saleAttrValue?.trim() == '') {
      ElMessage.error('属性值不能为空！')
      return
   }
   // 2.不能重复
   let repeat = row.spuSaleAttrValueList.find(item => {
      return item.saleAttrValueName == saleAttrValue
   })
   if (repeat) {
      ElMessage.error('属性值不能重复！')
      return
   }
   // 追加新的属性值对象
   row.spuSaleAttrValueList.push(newSaleAttrValue)
   // 切换为查看模式
   row.flag = false
}
// 保存按钮的回调
const save = async () => {
   // 整理参数
   // 1.照片墙数据
   SpuParams.value.spuImageList = imgList.value.map((item: any) => {
      return {
         imgName: item.name,
         imgUrl: (item.response && item.response.data) || item.url
      }
   })
   // 2.整理销售属性的数据
   SpuParams.value.spuSaleAttrList = saleAttr.value
   // 发请求：添加SPU|更新已有的SPU
   let result = await reqAddOrUpdateSpu(SpuParams.value)
   if (result.code == 200) {
      // 成功
      ElMessage.success(SpuParams.value.id ? '更新成功！' : '添加成功！')
      // 通知父组件切换场景为0
      $emit('changeScene', { flag: 0, params: SpuParams.value.id ? 'update' : 'add' })
   } else {
      // 失败
      ElMessage.error(SpuParams.value.id ? `更新失败！${result.data}` : `添加失败！${result.data}`)
   }
}
</script>

<style lang="scss" scoped></style>